#pragma once

namespace CoreInterface
{
	public ref class ImageDosHeader sealed
	{
	private:
		uint16   e_magic;                     // Magic number
		uint16   e_cblp;                      // Bytes on last page of file
		uint16   e_cp;                        // Pages in file
		uint16   e_crlc;                      // Relocations
		uint16   e_cparhdr;                   // Size of header in paragraphs
		uint16   e_minalloc;                  // Minimum extra paragraphs needed
		uint16   e_maxalloc;                  // Maximum extra paragraphs needed
		uint16   e_ss;                        // Initial (relative) SS value
		uint16   e_sp;                        // Initial SP value
		uint16   e_csum;                      // Checksum
		uint16   e_ip;                        // Initial IP value
		uint16   e_cs;                        // Initial (relative) CS value
		uint16   e_lfarlc;                    // File address of relocation table
		uint16   e_ovno;                      // Overlay number
		uint16   e_res[4];                    // Reserved words
		uint16   e_oemid;                     // OEM identifier (for e_oeminfo)
		uint16   e_oeminfo;                   // OEM information; e_oemid specific
		uint16   e_res2[10];                  // Reserved words
		uint32   e_lfanew;                    // File address of new exe header

	public:
		uint16 Get_magic() { return e_magic; }
		void Set_magic(uint16 value){e_magic = value;}

		uint16 Get_cblp() { return e_cblp; }
		void Set_cblp(uint16 value) { e_cblp = value; }

		uint16 Get_cp() { return e_cp; }
		void Set_cp(uint16 value) { e_cp = value; }

		uint16 Get_crlc() { return e_crlc; }
		void Set_crlc(uint16 value) { e_crlc = value; }

		uint16 Get_cparhdr() { return e_cparhdr; }
		void Set_cparhdr(uint16 value) { e_cparhdr = value; }

		uint16 Get_minalloc() { return e_minalloc; }
		void Set_minalloc(uint16 value) { e_minalloc = value; }

		uint16 Get_maxalloc() { return e_maxalloc; }
		void Set_maxalloc(uint16 value) { e_maxalloc = value; }

		uint16 Get_ss() { return e_ss; }
		void Set_ss(uint16 value) { e_ss = value; }

		uint16 Get_sp() { return e_sp; }
		void Set_sp(uint16 value) { e_sp = value; }

		uint16 Get_csum() { return e_csum; }
		void Set_csum(uint16 value) { e_csum = value; }

		uint16 Get_ip() { return e_ip; }
		void Set_ip(uint16 value) { e_ip = value; }

		uint16 Get_cs() { return e_cs; }
		void Set_cs(uint16 value) { e_cs = value; }

		uint16 Get_lfarlc() { return e_lfarlc; }
		void Set_lfarlc(uint16 value) { e_lfarlc = value; }

		uint16 Get_ovno() { return e_ovno; }
		void Set_ovno(uint16 value) { e_ovno = value; }

		Platform::Array<uint16>^ Get_res() { return ref new Platform::Array<uint16>(e_res, 4); }
		void Set_res(const Platform::Array<uint16>^ value)
		{
			if (value->Length <= 4)
			{
				for (unsigned index = 0; index < value->Length; ++index)
				{
					e_res[index] = value->get(index);
				}
			}	
		}

		uint16 Get_oemid() { return e_oemid; }
		void Set_oemid(uint16 value) { e_oemid = value; }

		uint16 Get_oeminfo() { return e_oeminfo; }
		void Set_oeminfo(uint16 value) { e_oeminfo = value; }

		Platform::Array<uint16>^ Get_res2() { return ref new Platform::Array<uint16>(e_res2, 10); }
		void Set_res2(const Platform::Array<uint16>^ value)
		{
			if (value->Length <= 10)
			{
				
				for (unsigned index = 0; index < value->Length; ++index)
				{
					e_res2[index] = value->get(index);
				}
			}
		}

		uint32 Get_lfanew() { return e_lfanew; }
		void Set_lfanew(uint32 value) { e_lfanew = value; }
	};

	public ref class ImageFileHeader sealed
	{
	private:
		uint16 Machine;
		uint16 NumberOfSections;
		uint32 TimeDateStamp;
		uint32 PointerToSymbolTable;
		uint32 NumberOfSymbols;
		uint16 SizeOfOptionalHeader;
		uint16 Characteristics;

	public:
		uint16 Get_Machine() { return Machine; }
		void Set_Machine(uint16 value) { Machine = value; }

		uint16 Get_NumberOfSections() { return NumberOfSections; }
		void Set_NumberOfSections(uint16 value) { NumberOfSections = value; }

		uint32 Get_TimeDateStamp() { return TimeDateStamp; }
		void Set_TimeDateStamp(uint32 value) { TimeDateStamp = value; }

		uint32 Get_PointerToSymbolTable() { return PointerToSymbolTable; }
		void Set_PointerToSymbolTable(uint32 value) { PointerToSymbolTable = value; }

		uint32 Get_NumberOfSymbols() { return NumberOfSymbols; }
		void Set_NumberOfSymbols(uint32 value) { NumberOfSymbols = value; }

		uint16 Get_SizeOfOptionalHeader() { return SizeOfOptionalHeader; }
		void Set_SizeOfOptionalHeader(uint16 value) { SizeOfOptionalHeader = value; }

		uint16 Get_Characteristics() { return Characteristics; }
		void Set_Characteristics(uint16 value) { Characteristics = value; }
	};

	public ref class ImageDataDirectory sealed
	{
	private:
		uint32 VirtualAddress;
		uint32 Size;

	public:
		ImageDataDirectory()
		{

		}

		ImageDataDirectory(uint32 nVirtualAddress, uint32 nSize)
		{
			VirtualAddress = nVirtualAddress;
			Size = nSize;
		}

		uint32 Get_VirtualAddress() { return VirtualAddress; }
		void Set_VirtualAddress(uint32 value) { VirtualAddress = value; }

		uint32 Get_Size() { return Size; }
		void Set_Size(uint32 value) { Size = value; }
	};

	public ref class ImageOptionalHeader sealed
	{
		uint16 Magic;
		byte   MajorLinkerVersion;
		byte   MinorLinkerVersion;
		uint32 SizeOfCode;
		uint32 SizeOfInitializedData;
		uint32 SizeOfUninitializedData;
		uint32 AddressOfEntryPoint;
		uint32 BaseOfCode;
		uint32 BaseOfData;
		uint64 ImageBase;
		uint32 SectionAlignment;
		uint32 FileAlignment;
		uint16 MajorOperatingSystemVersion;
		uint16 MinorOperatingSystemVersion;
		uint16 MajorImageVersion;
		uint16 MinorImageVersion;
		uint16 MajorSubsystemVersion;
		uint16 MinorSubsystemVersion;
		uint32 Win32VersionValue;
		uint32 SizeOfImage;
		uint32 SizeOfHeaders;
		uint32 CheckSum;
		uint16 Subsystem;
		uint16 DllCharacteristics;
		uint64 SizeOfStackReserve;
		uint64 SizeOfStackCommit;
		uint64 SizeOfHeapReserve;
		uint64 SizeOfHeapCommit;
		uint32 LoaderFlags;
		uint32 NumberOfRvaAndSizes;
		IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];

	public:
		uint16 Get_Magic() { return Magic; }
		void Set_Magic(uint16 value) { Magic = value; }

		uint8 Get_MajorLinkerVersion() { return MajorLinkerVersion; }
		void Set_MajorLinkerVersion(uint8 value) { MajorLinkerVersion = value; }

		uint8 Get_MinorLinkerVersion() { return MinorLinkerVersion; }
		void Set_MinorLinkerVersion(uint8 value) { MinorLinkerVersion = value; }

		uint32 Get_SizeOfCode() { return SizeOfCode; }
		void Set_SizeOfCode(uint32 value) { SizeOfCode = value; }
		
		uint32 Get_SizeOfInitializedData() { return SizeOfInitializedData; }
		void Set_SizeOfInitializedData(uint32 value) { SizeOfInitializedData = value; }

		uint32 Get_SizeOfUninitializedData() { return SizeOfUninitializedData; }
		void Set_SizeOfUninitializedData(uint32 value) { SizeOfUninitializedData = value; }

		uint32 Get_AddressOfEntryPoint() { return AddressOfEntryPoint; }
		void Set_AddressOfEntryPoint(uint32 value) { AddressOfEntryPoint = value; }

		uint32 Get_BaseOfCode() { return BaseOfCode; }
		void Set_BaseOfCode(uint32 value) { BaseOfCode = value; }

		uint32 Get_BaseOfData() { return BaseOfData; }
		void Set_BaseOfData(uint32 value) { BaseOfData = value; }

		uint64 Get_ImageBase() { return ImageBase; }
		void Set_ImageBase(uint64 value) { ImageBase = value; }

		uint32 Get_SectionAlignment() { return SectionAlignment; }
		void Set_SectionAlignment(uint32 value) { SectionAlignment = value; }
		
		uint32 Get_FileAlignment() { return FileAlignment; }
		void Set_FileAlignment(uint32 value) { FileAlignment = value; }

		uint16 Get_MajorOperatingSystemVersion() { return MajorOperatingSystemVersion; }
		void Set_MajorOperatingSystemVersion(uint16 value) { MajorOperatingSystemVersion = value; }

		uint16 Get_MinorOperatingSystemVersion() { return MinorOperatingSystemVersion; }
		void Set_MinorOperatingSystemVersion(uint16 value) { MinorOperatingSystemVersion = value; }

		uint16 Get_MajorImageVersion() { return MajorImageVersion; }
		void Set_MajorImageVersion(uint16 value) { MajorImageVersion = value; }

		uint16 Get_MinorImageVersion() { return MinorImageVersion; }
		void Set_MinorImageVersion(uint16 value) { MinorImageVersion = value; }

		uint16 Get_MajorSubsystemVersion() { return MajorSubsystemVersion; }
		void Set_MajorSubsystemVersion(uint16 value) { MajorSubsystemVersion = value; }

		uint16 Get_MinorSubsystemVersion() { return MinorSubsystemVersion; }
		void Set_MinorSubsystemVersion(uint16 value) { MinorSubsystemVersion = value; }

		uint32 Get_Win32VersionValue() { return Win32VersionValue; }
		void Set_Win32VersionValue(uint32 value) { Win32VersionValue = value; }

		uint32 Get_SizeOfImage() { return SizeOfImage; }
		void Set_SizeOfImage(uint32 value) { SizeOfImage = value; }

		uint32 Get_SizeOfHeaders() { return SizeOfHeaders; }
		void Set_SizeOfHeaders(uint32 value) { SizeOfHeaders = value; }

		uint32 Get_CheckSum() { return CheckSum; }
		void Set_CheckSum(uint32 value) { CheckSum = value; }

		uint32 Get_Subsystem() { return Subsystem; }
		void Set_Subsystem(uint32 value) { Subsystem = value; }

		uint16 Get_DllCharacteristics() { return DllCharacteristics; }
		void Set_DllCharacteristics(uint16 value) { DllCharacteristics = value; }

		uint64 Get_SizeOfStackReserve() { return SizeOfStackReserve; }
		void Set_SizeOfStackReserve(uint64 value) { SizeOfStackReserve = value; }

		uint64 Get_SizeOfStackCommit() { return SizeOfStackCommit; }
		void Set_SizeOfStackCommit(uint64 value) { SizeOfStackCommit = value; }

		uint64 Get_SizeOfHeapReserve() { return SizeOfHeapReserve; }
		void Set_SizeOfHeapReserve(uint64 value) { SizeOfHeapReserve = value; }

		uint64 Get_SizeOfHeapCommit() { return SizeOfHeapCommit; }
		void Set_SizeOfHeapCommit(uint64 value) { SizeOfHeapCommit = value; }

		uint32 Get_LoaderFlags() { return LoaderFlags; }
		void Set_LoaderFlags(uint32 value) { LoaderFlags = value; }

		uint32 Get_NumberOfRvaAndSizes() { return NumberOfRvaAndSizes; }
		void Set_NumberOfRvaAndSizes(uint32 value) { NumberOfRvaAndSizes = value; }

		Platform::Array<ImageDataDirectory^>^ Get_DataDirectory();
		void Set_DataDirectory(const Platform::Array<ImageDataDirectory^>^ value)
		{
			if (value->Length <= IMAGE_NUMBEROF_DIRECTORY_ENTRIES)
			{
				for (unsigned index = 0; index < value->Length; ++index)
				{
					DataDirectory[index].VirtualAddress = value->get(index)->Get_VirtualAddress();
					DataDirectory[index].Size = value->get(index)->Get_Size();
				}
			}
		}
		void Set_DataDirectory(ImageDataDirectory^ value, int pos)
		{
			DataDirectory[pos].Size = value->Get_Size();
			DataDirectory[pos].VirtualAddress = value->Get_VirtualAddress();
		}
	};

	public ref class ImageNtHeaders sealed
	{
	private:
		uint32 Signature;
		ImageFileHeader^ FileHeader = ref new ImageFileHeader();
		ImageOptionalHeader^ OptionalHeader = ref new ImageOptionalHeader();

	public:
		ImageNtHeaders();

		uint32 Get_Signature() { return Signature; }
		void Set_Signature(uint32 value) { Signature = value; }

		ImageFileHeader^ Get_FileHeader() {	return FileHeader; }
		void Set_FileHeader(ImageFileHeader^ value) { FileHeader = value; }

		ImageOptionalHeader^ Get_OptionalHeader() { return OptionalHeader; }
		void Set_OptionalHeader(ImageOptionalHeader^ value) { OptionalHeader = value; }
	};

	public ref class ImageSectionHeader sealed
	{
	private:
		byte    Name[IMAGE_SIZEOF_SHORT_NAME];
		union {
			uint32   PhysicalAddress;
			uint32   VirtualSize;
		} Misc;
		uint32 VirtualAddress;
		uint32 SizeOfRawData;
		uint32 PointerToRawData;
		uint32 PointerToRelocations;
		uint32 PointerToLinenumbers;
		uint16 NumberOfRelocations;
		uint16 NumberOfLinenumbers;
		uint32 Characteristics;

	public:
		ImageSectionHeader()
		{

		}

		Platform::Array<byte>^ Get_Name() { return ref new Platform::Array<byte>(Name, IMAGE_SIZEOF_SHORT_NAME); }
		void Set_Name(const Platform::Array<byte>^ value);

		uint32 Get_PhysicalAddress() { return Misc.PhysicalAddress; }
		void Set_PhysicalAddress(uint32 value) { Misc.PhysicalAddress = value; };

		uint32 Get_VirtualSize() { return Misc.VirtualSize; }
		void Set_VirtualSize(uint32 value) { Misc.VirtualSize = value; };

		uint32 Get_VirtualAddress() { return VirtualAddress; }
		void Set_VirtualAddress(uint32 value) { VirtualAddress = value; };

		uint32 Get_SizeOfRawData() { return SizeOfRawData; }
		void Set_SizeOfRawData(uint32 value) { SizeOfRawData = value; };

		uint32 Get_PointerToRawData() { return PointerToRawData; }
		void Set_PointerToRawData(uint32 value) { PointerToRawData = value; };

		uint32 Get_PointerToRelocations() { return PointerToRelocations; }
		void Set_PointerToRelocations(uint32 value) { PointerToRelocations = value; };

		uint32 Get_PointerToLinenumbers() { return PointerToLinenumbers; }
		void Set_PointerToLinenumbers(uint32 value) { PointerToLinenumbers = value; };

		uint16 Get_NumberOfRelocations() { return NumberOfRelocations; }
		void Set_NumberOfRelocations(uint16 value) { NumberOfRelocations = value; };

		uint16 Get_NumberOfLinenumbers() { return NumberOfLinenumbers; }
		void Set_NumberOfLinenumbers(uint16 value) { NumberOfLinenumbers = value; };

		uint32 Get_Characteristics() { return Characteristics; }
		void Set_Characteristics(uint32 value) { Characteristics = value; };
	};

	public ref class FunctionInfo sealed
	{
	private:
		Platform::String^ m_Name;
		uint64 m_SerialNumber;
		uint64 m_u64Address;
	public:
		FunctionInfo()
		{
			m_Name = "";
			m_SerialNumber = 0;
		}

		void Set_Name(Platform::String^ pName) { m_Name = pName; }
		Platform::String^ Get_Name() { return m_Name; }

		void Set_SerialNumber(uint64 value) { m_SerialNumber = value; }
		uint64 Get_SerialNumber() { return m_SerialNumber; }

		void Set_Address(uint64 value) { m_u64Address = value; }
		uint64 Get_Address() { return m_u64Address; }
	};

	public ref class ImportTableItem sealed
	{
	private:
		uint32 m_TimeDateStamp;
		Platform::String^ m_Name;
		Platform::Array<FunctionInfo^>^ m_FuncArray;

	public:
		ImportTableItem()
		{
			m_Name = nullptr;
			m_FuncArray = nullptr;
			m_TimeDateStamp = 0;
		}

		void Set_Name(Platform::String^ value) { m_Name = value; }
		Platform::String^ Get_Name() { return m_Name; }

		void Set_TimeDateStamp(uint32 value) { m_TimeDateStamp = value; }
		uint32 Get_TimeDateStamp() { return m_TimeDateStamp; }

		void Set_FuncArray(const Platform::Array<FunctionInfo^>^ value)
		{
			m_FuncArray = ref new Platform::Array<FunctionInfo^>(value->Length);
			for (unsigned i = 0; i < value->Length; ++i)
			{
				m_FuncArray->get(i) = value->get(i);
			}
		}
		Platform::Array<FunctionInfo^>^ Get_FuncArray() { return m_FuncArray; }
	};

	public ref class ExportFuncInfo sealed
	{
	private:
		uint32 m_Characteristics;
		uint32 m_TimeDateStamp;
		uint16 m_MajorVersion;
		uint16 m_MinorVersion;
		Platform::String^ m_Name;
		uint32 m_Base;

		Platform::Array<FunctionInfo^>^ m_FuncArray;
	public:
		void Set_Characteristics(uint32 value) { m_Characteristics = value; }
		uint32 Get_Characteristics() { return m_Characteristics; }

		void Set_TimeDateStamp(uint32 value) { m_TimeDateStamp = value; }
		uint32 Get_TimeDateStamp() { return m_TimeDateStamp; }

		void Set_MajorVersion(uint32 value) { m_MajorVersion = value; }
		uint32 Get_MajorVersion() { return m_MajorVersion; }

		void Set_MinorVersion(uint32 value) { m_MinorVersion = value; }
		uint32 Get_MinorVersion() { return m_MinorVersion; }

		void Set_Name(Platform::String^ value) { m_Name = value; }
		Platform::String^ Get_Name() { return m_Name; }

		void Set_Base(uint32 value) { m_Base = value; }
		uint32 Get_Base() { return m_Base; }

		void Set_FunctionArray(const Platform::Array<FunctionInfo^>^ value)
		{
			m_FuncArray = ref new Platform::Array<FunctionInfo^>(value->Length);
			for (unsigned i = 0; i < value->Length; ++i)
			{
				m_FuncArray->get(i) = value->get(i);
			}
		}
		Platform::Array<FunctionInfo^>^ Get_FunctionArray() { return m_FuncArray; }
	};

	public ref class PEInfo sealed
	{
	private:
		ImageDosHeader^ m_pImageDosHeader;
		ImageNtHeaders^ m_pImageNtHeaders;
		Platform::Array<ImageSectionHeader^>^ m_pImageSectionHeaderArray;
		Platform::Array<ImportTableItem^>^ m_pImportFunctionArray;
		ExportFuncInfo^ m_pExportFuncionInfo;
		Platform::String^ m_FileName;
		Platform::String^ m_FullPath;
	public:
		PEInfo()
		{

		}

		void Set_FileName(Platform::String^ value) { m_FileName = value; }
		Platform::String^ Get_FileName() { return m_FileName; }

		void Set_FullPath(Platform::String^ value) { m_FullPath = value; }
		Platform::String^ Get_FullPath() { return m_FullPath; }

		void Set_ImageDosHeader(ImageDosHeader^ header)	{m_pImageDosHeader = header;}
		ImageDosHeader^ Get_ImageDosHeader() { return m_pImageDosHeader; }

		void Set_ImageNtHeader(ImageNtHeaders^ header) { m_pImageNtHeaders = header; }
		ImageNtHeaders^ Get_ImageNtHeader() { return m_pImageNtHeaders; }

		void Set_SectionHeaders(const Platform::Array<ImageSectionHeader^>^ headerArray)
		{ 
			m_pImageSectionHeaderArray = ref new Platform::Array<ImageSectionHeader^>(headerArray->Length);
			for (unsigned i = 0; i < headerArray->Length; i++)
			{
				m_pImageSectionHeaderArray->get(i) = headerArray->get(i);
			}
		}
		Platform::Array<ImageSectionHeader^>^ Get_SectionHeaders() { return m_pImageSectionHeaderArray; }

		void Set_ImportFunction(const Platform::Array<ImportTableItem^>^ headerArray)
		{
			m_pImportFunctionArray = ref new Platform::Array<ImportTableItem^>(headerArray->Length);
			for (unsigned i = 0; i < headerArray->Length; ++i)
			{
				m_pImportFunctionArray->get(i) = headerArray->get(i);
			}
		}
		Platform::Array<ImportTableItem^>^ Get_ImportFunctionArray() { return m_pImportFunctionArray; }

		void Set_ExportFuncion(ExportFuncInfo^ value) { m_pExportFuncionInfo = value; }
		ExportFuncInfo^ Get_ExportFunction() { return m_pExportFuncionInfo; }
	};


}